package com.hrsaas.ext.spider.core;

import java.io.IOException;
import java.time.Duration;
import java.util.Map;
import java.util.function.Function;

import io.netty.handler.codec.http.HttpHeaders;

/**
 * <p>
 * 功能：请求实体对象
 * <p>
 * 
 * @author wangxiaoliang@kanzhun.com
 *
 *         2018年8月1日
 */
public interface HttpRequestBuilder {
	
	/**
	 * 添加header头
	 * @param key
	 * @param value
	 * @return
	 */
	<T> HttpRequestBuilder addHeader(String key, String value);
	
	/**
	 * 添加请求header头
	 * @param header
	 * @return
	 */
	<T> HttpRequestBuilder addHeaders(HttpHeaders headers);

	/**
	 * 添加referer 头
	 * @param referer
	 * @return
	 */
	public RequestBuilder addReferer(String referer);
	
	
	/**
	 * 添加 useragent 头
	 * @param referer
	 * @return
	 */
	public RequestBuilder addUserAgent(String useragent);
	
	/**
	 * 添加请求参数
	 * @param key
	 * @param value
	 * @return
	 */
	HttpRequestBuilder addQueryPair(String key, String value);

	default HttpRequestBuilder addQueryPairs(Map<String, Object> pairs, Function<Object, String> toString) {
		for (Map.Entry<String, Object> e : pairs.entrySet()) {
			if (e.getValue() != null) {
				addQueryPair(e.getKey(), toString.apply(e.getValue()));
			}
		}
		return this;
	}

	default HttpRequestBuilder addQueryPairs(Map<String, String> pairs) {
		for (Map.Entry<String, String> e : pairs.entrySet()) {
			if (e.getValue() != null) {
				addQueryPair(e.getKey(), e.getValue());
			}
		}
		return this;
	}

	/**
	 * 设置域名或ip
	 * @param host
	 * @return
	 */
	HttpRequestBuilder setHost(String host);

	/**
	 * 设置请求url
	 * @param path
	 * @return
	 */
	HttpRequestBuilder setPath(String path);

	/**
	 * 设置端口
	 * @param port
	 * @return
	 */
	HttpRequestBuilder setPort(int port);

	/**
	 * 请求协议
	 * @param protocol
	 * @return
	 */
	HttpRequestBuilder setProtocol(String protocol);

	/**
	 * 检查并解析url参数，包括协议，端口，域名，参数等的解析
	 *
	 * @param url
	 * @return
	 */
	HttpRequestBuilder setURL(String url);

	/**
	 * 发起请求，消息返回后通知给response
	 * 若之后的请求是同属域名，默认会对响应的header及cookie进行处理
	 * @param response
	 * @return
	 */
	ResponseFuture execute(ResponseHandler<?> response);

	/**
	 * 传输对象，可以是文件，流或是字符串
	 * 
	 * @param obj
	 * @param contentType
	 * @return
	 * @throws IOException
	 */
	HttpRequestBuilder setBody(Object obj) throws Exception;

	/**
	 * 服务器响应回调函数
	 * @param event
	 * @param r
	 * @return
	 */
	<T> HttpRequestBuilder on(Class<? extends State<T>> event, Receiver<T> r);

	/**
	 * 服务器响应回调函数
	 * @param event
	 * @param r
	 * @return
	 */
	<T> HttpRequestBuilder on(StateType event, Receiver<T> r);

	/**
	 * 服务器响应回调函数
	 * @param r
	 * @return
	 */
	HttpRequestBuilder onEvent(Receiver<State<?>> r);

	/**
	 * 请求不添加host header头
	 * @return
	 */
	HttpRequestBuilder noHostHeader();

	/**
	 * 请求不添加connect header头
	 * @return
	 */
	HttpRequestBuilder noConnectionHeader();

	/**
	 * 请求不添加date header头
	 *
	 * @return this
	 */
	HttpRequestBuilder noDateHeader();

	/**
	 * 设置 cookie 头
	 * @param store
	 * @return
	 */
	HttpRequestBuilder addCookieStore(CookieStore store);

	/**
	 * 设置 请求超时时间
	 * @param timeout
	 * @return
	 */
	HttpRequestBuilder setTimeout(Duration timeout);

	/**
	 * @return
	 */
	HttpRequestBuilder dontAggregateResponse();

}
